#ifndef _BID_SERVICE_H_
#define _BID_SERVICE_H_

#include "util.h"
#include <sys/time.h>

#define MODE_DYNAMIC_THREADS  		0
#define MODE_POOLED_THREADS   		1
#define BSD_MAX_CMD_LINE_LEN		1024
#define BSD_MAX_CMD_NAME_LEN      	128

#define BSD_CMD_BUF_MAX_SIZE      	1024
#define BSD_RES_BUF_MAX_SIZE       	1024
#define BSD_ERR_MSG_MAX_SIZE     	1024
#define BSD_MAX_CMD_ARGS			16

#define BSD_SESSION_CTX     		0xFFFFFFFF
#define BSD_MAX_SESSION_COUNT   	999
#define BSD_MAX_IDLE_TIME       	1
#define INVALID_FD          		-1

typedef enum bid_service_event_def {
	BSE_EV_SUCCESS,
	BSE_EV_ACCEPT,
	BSE_EV_REJECT,
	BSE_EV_CONN_ERROR,
	BSE_EV_INVALID_CMD,
	BSE_EV_INVALID_SYNTAX,
	BSE_EV_INVALID_STATE,
	BSE_EV_REPORT_ERROR,
	BSE_EV_END
}bid_service_event;

typedef enum bid_service_state_dev {
	BSE_ST_CONNECTED,
	BSE_ST_VALIDATING_CONNECTION,
	BSE_ST_SENDING_GREETING,
	BSE_ST_RECEIVING_CMD,
	BSE_ST_VALIDATING_CMD,
	BSE_ST_REPORTING_ERROR,
	BSE_ST_EXECUTING_CMD,
	BSE_ST_TERMINATE_SESSION,
	BSE_ST_CLOSING_CONNECTION,
	BSE_ST_END_SESSION
}bid_service_state;

typedef int bid_session_state;
#define UNAUTH 0x01
#define AUTH 0x10


/* Data structure to be passed to thread */
typedef struct session_ctx_def {
    long eye_catcher; //Ctx Validator

    //Session owner infromation.
    pthread_t this; //Pointer to the thread owner of this ctx.
    int session_id;   //session identifier.
    char* client_ip;  //client ip address
    int client_port;  //client port
    int sock_fd;       //client socket

    //Transition details.
    bid_service_event event;
    bid_service_state prev_state;
    bid_service_state curr_state;

    //Session tracker fields
    time_t connect_time;
    time_t logon_time;
    time_t command_time;

    //Command details
    bid_session_state session_status;
    char cmd_buff[BSD_CMD_BUF_MAX_SIZE+1];
    char *cmd;
    void *cmd_handler;
    char *arg[BSD_MAX_CMD_ARGS];
    int arg_count;

    char resp_buff[BSD_RES_BUF_MAX_SIZE+1];
    char error_msg[BSD_ERR_MSG_MAX_SIZE+1];

} session_ctx;


typedef bid_service_event (bid_service_action) (session_ctx * ctx);

typedef struct bid_transition_key_def {
	bid_service_state current_state;
	bid_service_event event;
}bid_fsm_transition_key;

typedef bid_service_event (bid_cmd_handler) (session_ctx* ctx);

typedef struct bid_cmd_def {
	char *command;
	bid_cmd_handler *handler;
	int  arg_cnt;
	bid_session_state state;
}bid_cmd;

/****************************************************************************************
 * Routines.
 ****************************************************************************************/

void initialize_context(session_ctx* ctx);

/* fsm routines */
void fsm (session_ctx *ctx);

//bid_service_action do_connect;
bid_service_action do_validate_connection;
bid_service_action do_send_greeting;
bid_service_action do_receive_command;
bid_service_action do_validate_command;
bid_service_action do_report_error;
bid_service_action do_execute_command;
bid_service_action do_close_connection;
bid_service_action do_terminate_session;

/* cmd routines */
void handle_bid_service_connect(int fd);
bid_cmd_handler auth_handler;
bid_cmd_handler auth_md5_handler;
bid_cmd_handler auth_md5_res_handler;
bid_cmd_handler list_items_handler;
bid_cmd_handler bid_handler;
bid_cmd_handler list_my_bids_handler;
bid_cmd_handler list_my_items_handler;






#endif //_BID_SERVICE_H_
